package com.northpool.operator.analysis.dataset;

import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.common.algorithm.OperatorTestBuild;
import com.northpool.operator.common.algorithm.TestParamBuilder;
import com.northpool.operator.common.database.DatabaseUtils;
import com.northpool.operator.common.stpclient.StpClientOperatorBase;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.param.custom.DatasetParam;
import com.northpool.operator.type.TypeEnum;
import com.northpool.spatial.grid.Constants;
import com.northpool.stpclient.bean.BaseResponse;
import com.northpool.stpclient.bean.overlay.GapCheckPlan;
import com.northpool.stpclient.modules.geoprocess.overlay.IOverlayOperator;
import org.apache.commons.lang3.StringUtils;

@OperatorInfo(
        ref = "GapCheckOperator",
        name = "缝隙检查",
        description = "用于单个图层内相交图斑的内部缝隙检查分析"
)
public class GapCheckOperator extends StpClientOperatorBase {

    @InputParams({
            @InputParam(ref = "dataset", name = "数据集", desc = "数据集包含数据源ID和数据表名称的JSON描述，如: {\"dataSourceId\":\"xxx-xxx\",\"tableName\":\"table\"}", type = TypeEnum.DB, required = true),
            @InputParam(ref = "sqlFilter", name = "SQL过滤条件", desc = "SQL过滤条件, 如: dlmc = '旱地'", type = TypeEnum.STRING, required = false, value = ""),
            @InputParam(ref = "gridUnit", name = "格网单位", desc = "瓦片格网单位，枚举值: degree、meter", type = TypeEnum.STRING, value = "degree"),
            @InputParam(ref = "wkt", name = "WKT范围", desc = "WKT范围，如: POLYGON((113.0 34.0, 114.0 34.0, 114.0 35.0, 113.0 35.0, 113.0 34.0))", type = TypeEnum.STRING),
            @InputParam(ref = "targetDataSourceId", name = "目标数据源ID", desc = "目标数据源ID", type = TypeEnum.DATASOURCE, required = true),
            @InputParam(ref = "targetTableName", name = "目标表名称", desc = "目标表名称", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "targetLevel", name = "数据处理层级", desc = "用于数据处理时的任务格网层级，根据数据量大小和图斑大小决定", value = "12", type = TypeEnum.STRING, required = false, testValue = "15"),
    })
    public GapCheckOperator() {
        super();
    }

    public static void main(String[] args) throws Exception {
        OperatorTestBuild.execute(GapCheckOperator.class,
                TestParamBuilder.aBuilder()
                        .param("dataset", "")
                        .param("sqlFilter", "dlmc = '旱地'")
                        .param("gridUnit", "degree")
                        .param("wkt", "")
                        .param("targetDataSourceId", "storage")
                        .param("targetTableName", "result.czkfbj2022_4301_gap_select")
                        .param("targetLevel", "15")
                        .build()
        );
    }

    @Override
    public void execute(ParamTool params) throws Exception {
        DatasetParam dataset = params.getDataset("dataset");

        String dataSourceId = dataset.getDataSourceId();
        String tableName = dataset.getTableName();
        String sqlFilter = params.getStr("sqlFilter");
        String gridUnit = params.getStr("gridUnit");
        String wkt = params.getStr("wkt");
        String spatialRelation = "INTERSECTS";
        String targetDataSourceId = params.getStr("targetDataSourceId");
        String targetTableName = params.getStr("targetTableName");
        String targetLevel = params.getStr("targetLevel");

        String dataSourceJson = DatabaseUtils.getDataSourceJson(dataSourceId);
        String targetDataSourceJson = DatabaseUtils.getDataSourceJson(targetDataSourceId);

        IOverlayOperator operator = this.client.overlayOperator();

        GapCheckPlan plan = new GapCheckPlan();
        plan.setDataSourceStr(dataSourceJson);
        plan.setTableName(tableName);
        plan.setSqlFilter(sqlFilter);
        plan.setHasRootGap(false);
        if(StringUtils.isNotBlank(wkt)) {
            plan.setWkt(wkt);
        }
        plan.setGridUnit(Constants.GRID_UNIT.valueOf(gridUnit));
        plan.setSpatialRelation(spatialRelation);

        plan.setTargetLevel(Integer.valueOf(targetLevel));
        plan.setTargetDataSourceStr(targetDataSourceJson);
        plan.setTargetTableName(targetTableName);

        BaseResponse response = operator.startGapCheck(plan);

        String requestId = response.getRequestId();
        operator.onStart(requestId, () -> {
            this.error("缝隙检查开始");
        });
        operator.onSuccess(requestId, () -> {
            this.error("缝隙检查成功");
            String log = operator.log(response.getRequestId());
            this.error(log);
            this.successExit();
        });
        operator.onError(requestId, () -> {
            this.error("缝隙检查失败");
            String log = operator.log(response.getRequestId());
            this.error(log);
            this.failedExit();
        });
        this.waiting(24);
    }
}
